import time
import uuid
import json
import hashlib
import requests
from urllib.parse import urlencode

def md5_string(text: str, encoding: str = 'utf-8', uppercase: bool = True) -> str:
    """计算字符串的 MD5 哈希值"""
    md5 = hashlib.md5()
    md5.update(text.encode(encoding))
    return md5.hexdigest().upper() if uppercase else md5.hexdigest()


mchNo = "E259974077640"  # 通联企业编号
appId = "68073139e4b01550865a9e39"
appId = "68073139e4b01550865a9e39"
md5_key = "utibjj906tnnz09lutu4urrkeyx6ap95id2ps63xgbe789qqqgpk1d7e1d0ayrhicz0jhd7j20bdhnrbtmdr2ylrl2j455wp05mu7l65bbfh3qmc9h26sqaqjqhg7z4v"

#mchNo = "E249974088543"  # 通联企业编号  demo
#appId = "66d08165e4b042d57df3b33e"
#md5_key = "sykliu9uxln7zppmld43vsxb93vvu3idriq3q1c06whvh4b6rtxm835w8saa9yvabe7spucyd88sv8zd88svq3eoeo5omzk5us5ctcpra80m9bexltkob2cncep1l9iq"


class AllinPay:
    def __init__(self):
        self.mchNo = mchNo
        self.appId = appId
        self.md5_key = md5_key
        self.base_url = "https://tp.allinpay.com/pay/api"
        self.subAppid = "wx63898f98b915581b"
        signMap = dict()
        signMap["mchNo"] = self.mchNo
        signMap["appId"] = self.appId
        signMap["version"] = "1.0"
        signMap["signType"] = "MD5"
        self.signMap = signMap

    def unifiedOrder(self, mchOrderNo, amount):
        """
        统一下单
        """
        amount = str(amount)
        mchOrderNo = str(mchOrderNo)
        reqTime = time.time() * 1000
        reqTime = str(int(reqTime))
        signMap = self.signMap
        signMap["reqTime"] = reqTime
        signMap["mchOrderNo"] = mchOrderNo
        signMap["wayCode"] = "YW_PAY"
        signMap["amount"] = amount
        signMap["currency"] = "cny"
        signMap["body"] = "test"
        signMap["notifyUrl"] = "https://c2c.kalaibao.com/shop/api/payment_notice"
        signMap["channelExtra"] = json.dumps({"apptype": "03", "appname": self.subAppid})
        sign = self._get_sign(signMap)
        signMap["sign"] = sign
        url = self.base_url + "/pay/unifiedOrder"
        content = requests.post(url, json=signMap, data=signMap)
        return content


    def refundOrder(self, reqTime, mchRefundNo, mchOrderNo, refundAmount):
        """
        mchRefundNo 订单号
        """
        signMap = self.signMap
        signMap["reqTime"] = reqTime
        signMap["mchRefundNo"] = mchRefundNo
        signMap["mchOrderNo"] = mchOrderNo
        signMap["refundAmount"] = refundAmount
        signMap["currency"] = "cny"
        signMap["refundReason"] = "test"
        signMap["extParam"] = mchOrderNo
        signMap["notifyUrl"] = "https://c2c.kalaibao.com/shop/api/refund_notice"
        sign = self._get_sign(signMap)
        signMap["sign"] = sign
        url = self.base_url + "/refund/refundOrder"
        content = requests.post(url, json=signMap, data=signMap)
        data = json.loads(content.content)
        return data

# {"code":0,"data":{"channelOrderNo":"532506171543009670218","mchRefundNo":"1750158156250953521","payAmount":699,"refundAmount":699,"refundOrderId":"R1934929763136966657","state":1},"msg":"SUCCESS","sign":"AF33189C113DC4FD23770BF7EC2AB479"}

    def _get_sign(self, signMap):
        sign_ing = sorted(signMap.items())
        s = ""
        for i in sign_ing:
            s+= str(i[0]) + "=" + str(i[1]) + "&"
        string_a = s + "key=" + self.md5_key
        sign = md5_string(string_a)
        return sign

    def refund_query(self, reqTime, mchRefundNo, mchOrderNo, refundAmount):
        """
        退款订单查询
        """
        signMap = self.signMap
        signMap["reqTime"] = reqTime
        signMap["mchRefundNo"] = mchRefundNo
        signMap["mchOrderNo"] = mchOrderNo
        signMap["refundAmount"] = str(refundAmount)
        signMap["refundReason"] = "coffee订单失败"
        sign = self._get_sign(signMap)
        signMap["sign"] = sign
        url = self.base_url + "/refund/query"
        content = requests.post(url, json=signMap, data=signMap)
        print(content.text)
        print(content.content)
        return content

    def validate_sign(self, data):
        # data = {'ifCode': 'allinpay', 'payOrderId': 'P1934884281211224065', 'mchOrderNo': '202503241650283806558476', 'subject': 'test', 'sign': 'A1C9024605183C3C93689D9EAED2CABD', 'channelOrderNo': '042506171602150194158', 'reqTime': '1750147343937', 'body': 'test', 'createdAt': '1750147336000', 'channelFeeAmount': '0', 'appId': '68073139e4b01550865a9e39', 'successTime': '1750147344000', 'signType': 'MD5', 'currency': 'cny', 'state': '2', 'mchNo': 'E259974077640', 'amount': '1', 'mchName': '好互咖啡', 'wayCode': 'YW_PAY', 'channelAcctType': '00', 'expiredTime': '2025-06-17 17:02:16', 'clientIp': '47.93.202.86', 'channelUser': '621030******1127'}
        copy_data = data.copy()
        for k,v in data.items():
            if v is None:
                del copy_data[k]
        print(copy_data)
        sign1 = copy_data.pop("sign")
        sign2 = self._get_sign(copy_data)
        return sign1 == sign2



if __name__ == '__main__':
    alliPay = AllinPay()
    alliPay.refund_query("202503241650283806558476")
    # alliPay.unifiedOrder(1,1)
